home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ShareWare OnLine 2
/
ShareWare OnLine Volume 2 (CMS Software)(1993).iso
/
util2
/
pgp22src.zip
/
SRC
/
3B1_6800.S
next >
Wrap
Text File
|
1993-03-07
|
6KB
|
176 lines
# 3B1 Assembler - primitives for multi-precision math on the MC68010
#
# Written by Rob Stampfli 19-Oct-92 for 3B1
# Assembler: 3B1 native assembler
#
# Note that the function P_SETP of the Intel primitives is not used.
# `set_precision' has to be defined just like in `PORTABLE' mode.
global global_precision
global P_ADDC
global P_SUBB
global P_ROTL
global P_SETP
global P_SMUL
text
#boolean P_ADDC(unitptr r1, unitptr r2, boolean carry);
# /* multiprecision add with carry r2 to r1, result in r1 */
#Parameters: A0.l: r1, A1.l: r2, D0.b: carry
#Result: D0.b: new carry
#Modifies: D0-D2/A0-A1
P_ADDC: mov.l 4(%sp),%a0 # fetch first argument: r1
mov.l 8(%sp),%a1 # fetch second argument: r2
mov.l 12(%sp),%d1 # fetch third argument: carry
mov.l %d2,-(%sp) # save d2 -- not a Unix-PC scratch reg
mov.w global_precision,%d2 # fetch # of 16 bit units
mov.w %d2,%d0 # copy units
lsl.w &1,%d0 # convert units to bytes (1 unit = 2 bytes)
add.w %d0,%a0 # point r1 to 1 past least significant unit
add.w %d0,%a1 # point r2 to 1 past least significant unit
lsr.w &5,%d0 # conv bytes to (units/16); # times thru loop1
and.w &15,%d2 # = (units%16); # times thru loop2
lsr.b &1,%d1 # set X-bit as specified by carry arg
bra adbf1
aloop1: #REPT 8 # 16 units per loop
addx.l -(%a1),-(%a0)
addx.l -(%a1),-(%a0)
addx.l -(%a1),-(%a0)
addx.l -(%a1),-(%a0)
addx.l -(%a1),-(%a0)
addx.l -(%a1),-(%a0)
addx.l -(%a1),-(%a0)
addx.l -(%a1),-(%a0)
adbf1: dbf %d0,aloop1
bra adbf2
aloop2: addx.w -(%a1),-(%a0)
adbf2: dbf %d2,aloop2
scs %d0 #set returned carry
mov.l (%sp)+,%d2 # restore d2
rts
#boolean P_SUBB(unitptr r1, unitptr r2, boolean borrow);
# /* multiprecision subtract with borrow, r2 from r1, result in r1 */
#Parameters: A0.l: r1, A1.l: r2, D0.b: borrow
#Result: D0.b: new borrow
#Modifies: D0-D2/A0/A1
P_SUBB: mov.l 4(%sp),%a0 # fetch first argument: r1
mov.l 8(%sp),%a1 # fetch second argument: r2
mov.l 12(%sp),%d1 # fetch third argument: carry
mov.l %d2,-(%sp) # save d2 -- not a Unix-PC scratch reg
mov.w global_precision,%d2 # fetch # of 16 bit units
mov.w %d2,%d0 # copy units
lsl.w &1,%d0 # convert units to bytes (1 unit = 2 bytes)
add.w %d0,%a0 # point r1 to 1 past least significant unit
add.w %d0,%a1 # point r2 to 1 past least significant unit
lsr.w &5,%d0 # conv bytes to (units/16); # times thru loop1
and.w &15,%d2 # = (units%16); # times thru loop2
lsr.b &1,%d1 # set X-bit as specified by carry arg
bra bdbf1
bloop1: #REPT 8 # 16 units per loop
subx.l -(%a1),-(%a0)
subx.l -(%a1),-(%a0)
subx.l -(%a1),-(%a0)
subx.l -(%a1),-(%a0)
subx.l -(%a1),-(%a0)
subx.l -(%a1),-(%a0)
subx.l -(%a1),-(%a0)
subx.l -(%a1),-(%a0)
bdbf1: dbf %d0,bloop1
bra bdbf2
bloop2: subx.w -(%a1),-(%a0)
bdbf2: dbf %d2,bloop2
scs %d0 # set returned carry
mov.l (%sp)+,%d2 # restore d2
rts
#boolean P_ROTL(unitptr r1, boolean carry);
# /* multiprecision rotate left 1 bit with carry, result in r1. */
#Parameters: A0.l: r1, D0.b: carry
#Result: D0.b: new carry
#Modifies: D0-D2/A0
P_ROTL: mov.l 4(%sp),%a0 # fetch first argument: r1
mov.l 8(%sp),%d1 # fetch second argument: carry
mov.l %d2,-(%sp) # save d2 -- not a Unix-PC scratch reg
mov.w global_precision,%d2 # fetch # of 16 bit units
mov.w %d2,%d0 # copy units
lsl.w &1,%d0 # convert units to bytes (1 unit = 2 bytes)
add.w %d0,%a0 # point r1 to 1 past least significant unit
lsr.w &5,%d0 # conv bytes to (units/16); # times thru loop1
and.w &15,%d2 # = (units%16); # times thru loop2
lsr.b &1,%d1 # set X-bit as specified by carry arg
bra cdbf1
cloop1: #REPT 16 # note roxl.l not valid on 68010
roxl.w &1,-(%a0)
roxl.w &1,-(%a0)
roxl.w &1,-(%a0)
roxl.w &1,-(%a0)
roxl.w &1,-(%a0)
roxl.w &1,-(%a0)
roxl.w &1,-(%a0)
roxl.w &1,-(%a0)
roxl.w &1,-(%a0)
roxl.w &1,-(%a0)
roxl.w &1,-(%a0)
roxl.w &1,-(%a0)
roxl.w &1,-(%a0)
roxl.w &1,-(%a0)
roxl.w &1,-(%a0)
roxl.w &1,-(%a0)
cdbf1: dbf %d0,cloop1
bra cdbf2
cloop2: roxl.w &1,-(%a0)
cdbf2: dbf %d2,cloop2
scs %d0 # set returned carry
mov.l (%sp)+,%d2 # restore d2
rts
#void P_SETP(short nbits);
# /* sets working precision to specified number of bits. */
# /* only to minimize portation differences */
#Parameters: --
#Result: --
P_SETP: rts
#void P_SMUL(MULTUNIT *prod, MULTUNIT *multiplicand, MULTUNIT multiplier)
# /* multiprecision multiply */
#Parameters: A0.l: prod, A1.l: multiplicand, D0.w: multiplier
#Modifies: D0-D4/A0-A1
#Result: --
#Note: prod and multiplicand have already been adjusted to point to LSB
# prior to making the call.
P_SMUL: mov.l 4(%sp),%a0 # fetch first argument: prod
mov.l 8(%sp),%a1 # fetch second argument: multiplicand
mov.l 12(%sp),%d0 # fetch third argument: multiplier
mov.l %d2,-(%sp) # save d2 -- not a Unix-PC scratch reg
mov.l %d3,-(%sp) # save d3 -- not a Unix-PC scratch reg
mov.l %d4,-(%sp) # save d4 -- not a Unix-PC scratch reg
clr.l %d2 # clear the carry register
clr.l %d4 # clear upper half of temp reg for prod
add.w &2,%a0 # position prod to 1 beyond LSB
add.w &2,%a1 # position multiplicand to 1 beyond LSB
mov.w global_precision,%d3 # fetch size of multiplicand
bra ddbf1
dloop: mov.w -(%a1),%d1 # fetch multiplicand
mulu.w %d0,%d1 # multiply by multiplier
mov.w -(%a0),%d4 # fetch prod
add.l %d4,%d1 # add in prod
add.l %d2,%d1 # add in carry
mov.w %d1,(%a0) # store result back to prod
swap.w %d1 # fetch carry info (upper 16 bits of mult)
mov.w %d1,%d2 # and move it into carry
ddbf1: dbf %d3,dloop
mov.w %d2,-(%a0) # store carry
mov.l (%sp)+,%d4
mov.l (%sp)+,%d3
mov.l (%sp)+,%d2
rts